import pygame, sys, random, math, datetime, colour, debug
#pygame - the main engine
#sys - allows system commands like closing windows
#random - random number engine
#math - mathematical operations
#datetime - date and time data
#colour - simple colour dicionary (I wrote this one xD)

class gui(object):
    def __init__(self, x, y,level=0):
        print "Debug Level:",level
        self.resolution = x, y
        self.screen_center = (x/2, y/2)
        self.x_fraction, self.y_fraction = x/800.0, y/600.0

        self.error=debug.debug("main",level)
        self.error.bug("Game initialised: Min debug level 5 to display this message",5)
        
        self.menu = {}
        self.fonts = {}
        self.populate_fonts()
        
        self.screen = pygame.display.set_mode(self.resolution, pygame.RESIZABLE)
        
        
    def get_font_dict(self,size,image_file):
        """returns a dictionary of font:location for use with populate_fonts"""
        import string
        i=0
        font_dict={}
        self.error.bug((self.menu,self.fonts),5)
        
        self.error.bug(("size:",size,"font retrieved"),4)
        try:
            for y in range(0,8):
                for x in range(0,8):
                    box=x*size,y*size,(x*size)+size,(y*size)+size
                    imagedata=image_file.crop(box)
                    
                    img_mode = imagedata.mode
                    img_size = imagedata.size
                    img_data = imagedata.tostring()

                    surface = pygame.image.fromstring(img_data, img_size, img_mode)
                                    
                    font_dict[string.ascii_lowercase[i]]= surface
                    i+=1
        except:
            font_dict["size"]=size
            font_dict[" "]="blank"
            return font_dict
	    
    def populate_fonts(self):        
        import os
        from PIL import Image
        path="../Graphics/GUI/fonts/"
        dirlist=os.listdir(path)
        for font in dirlist:
            img_file=Image.open(path+str(font))
            resolution=img_file.size
            self.fonts[font[:-4]]=(self.get_font_dict(resolution[0]/8,img_file))


    def input_loop(self):
        self.running = True
      
            
        ##event handler 
        while self.running:
            
            # Consumes events from the pygame event queue. Blocks until there is an event available to consume.
            event = pygame.event.wait()    
            #print event
            if event.type == pygame.MOUSEBUTTONDOWN:
                mouseclick = event.dict["pos"]
                mousebutton = event.dict["button"]
                

                self.error.bug(("user clicked at", mouseclick, "with", mousebutton),3)
                ##check if mouseclick is in a button's rect
                for list in self.menu:
                    if list[0:2] != "bg" and self.menu[list][6].collidepoint(mouseclick):
                        self.error.bug(("USER CLICKED ON:", self.menu[list][2]),3)
                        ##test to load a new GUI on buttonclick: will parse independantly based on the button type (not yet written)
                        # self.build_menu(self.menu[list][2])
                       
                       
                        # Call the function associated with this button
                        self.menu[list][8]()
                        break

            ##keypress handler
            if event.type == pygame.KEYDOWN:
                keypress = event.dict["unicode"]
                if keypress == "\x1b":
                    self.close_gui("closing GUI loop and event handler (ESC KEY)")

            ##screen resize handler
            if event.type == pygame.VIDEORESIZE:
                x = event.dict["w"]
                y = event.dict["h"]
                self.error.bug(("resized to", event.dict["size"]),2)
                self.resolution = x, y
                self.screen_center = (x / 2, y / 2)
                self.x_fraction, self.y_fraction = x / 800.0, y / 600.0
                
                self.screen = pygame.display.set_mode(self.resolution, pygame.RESIZABLE)
######                print "The current menu is: " + str(self.menu)
                self.build_menu(self.menu)
                
            ##quit handler
            if event.type == pygame.QUIT:
                ##end event handler (to prevent the queue filling up)
                self.close_gui("closing GUI loop and event handler")
                
            ## Mouse motion handler. Might be useful in the future if we want to animate the buttons
            ## When they are hovered over
            if event.type == pygame.MOUSEMOTION:
                pos = event.dict["pos"]
                    

                        
        #except:
##            self.close_gui("GUI experienced and error and had to close... I hope you figure out what the error was because I HAVE NO IDEA!")
                        
    def close_gui(self, message="GUI closed using function"):
        """terminates GUI_loop() including event handler, while printing a message to console"""
        print message
        print self.error
        self.error.bug(message,2)
        self.running = False
        pygame.quit()
        sys.exit()
        
        
    def build_menu(self, newmenu):
        self.menu = newmenu
        
        
    #    self.menu.clear()
    #    self.menu.update(newmenu)
        
######        print "build_menu dict: " + str(self.menu)
        
        #self.menu = newmenu
        
        #try:
        if self.menu == "null" or self.menu < 0:
           message = "no menu selected for display:", self
           self.close_gui(message)
        
        else:
            for list in self.menu:
                print self.menu[list][0]
                if self.menu[list][0]=="background":
                   
                    self.menu[list][2] = pygame.image.load(str("../Graphics/GUI/backgrounds/" + str(random.choice(self.menu[list][1])) + ".png"))
                    self.menu[list][3] = self.menu[list][2].get_rect(center=self.screen_center)
                    self.screen.blit(self.menu[list][2], self.menu[list][3])
                    self.error.bug(self.menu[list],4)
                    
                if self.menu[list][0] in ("button","label"):
                    ##load IMAGE file (for GUI element)
                    ##define RECT for loaded image file and load at listed coordinates

                    ##button images
                    self.menu[list][5] = pygame.image.load(str("../Graphics/GUI/menus/" + self.menu[list][2] + str(self.menu[list][4]) + ".png"))
                    self.menu[list][6] = self.menu[list][5].get_rect(center=(self.menu[list][1][0] * self.x_fraction, self.menu[list][1][1] * self.y_fraction))
        
                    ##text
                    font=self.menu[list][7]
                    print "font:",font
                    text=self.menu[list][3]
                    print text
                    location=self.menu[list][1][0]* self.x_fraction,self.menu[list][1][1]* self.y_fraction
                    print location
###7 is the font name
                    ##blit (draw) button texture THEN button text (for each GUI element)

                    self.screen.blit(self.menu[list][5], self.menu[list][6])
                    self.draw_letter(font,text,location,center=1)
                    
            pygame.display.flip()
######            print self.menu

    def draw_letter(self,font="null",text="null",location=(0,0),center=1):
        
        if font != "null":
            size=self.fonts[font]["size"]
            location=[location[0],location[1]]
            if center==0:
                x_offset,y_offset=0,0
            elif center==1:
                x_offset,y_offset=-(len(text)*size)/2,-(size/2)
            write_head=[location[0]+x_offset,location[1]+y_offset]
            for letter in range(0,len(text)):
                if text[letter]==" ":
                    write_head[0]+=size
                    
                    
                else:
                    self.error.bug((self.fonts[font][text[letter]],[text[letter]],"at",location),4)
                    self.screen.blit(self.fonts[font][text[letter]],write_head)
                    write_head[0]+=size
                    
                    
                    
            

# Entry point for debugging
def debugging():
    test = gui(800, 600)
    
    #Build the menu UI
    test.build_menu("main_menu");
    
    # Listen for user input
    test.input_loop()



